# Memory management

The following topic describes how to use the Memory Management ADDON API.

## Memory management background

The Replicate ADDON Memory Management API provides Add-on developers with the ability to allocate memory for use within their add-on modules. Allocation is done in the context of memory pools, where a given pool lets the caller allocate multiple buffers, and then free them all in a single operation when the memory is no longer needed.

Information noteIt is not possible to free a specific allocated buffer, only the pool under which it was created.

There are two types of memory pools available with the memory management API:

* Global pools

  Global pools are memory pools created from the memory pool provided during add-on initialization. These pools remain active until explicitly deallocated by the add-on or until the replication process ends. Use of a global pool for buffer allocation after add-on initialization needs to be protected by a critical section (in other words, it is not safe to allocate buffers using a pool that might be used at the same time on a different thread).

* Thread-specific pools

  Thread-specific pools are memory pools created from the memory pool returned by the get\_ctx\_pool() function when called outside of the add-on initialization. Examples of threads within a replication task using the ADDON include the Full Load threads and the Change Data Capture thread. Thread-specific pools and buffers allocated through them are automatically freed when the thread in which they were created terminates.

Information noteAll active memory pools created by the ADDON Memory Management APIs will appear in the Replicate Memory Report.

## Memory management methods

The following methods can be called to utilize Replicate's memory management procedures.

### create\_pool

Creates a new memory pool from another memory pool (a “child pool”). Creating a child pool lets the developer clear or destroy the memory pool to release memory. When called during ADDON initialization (using the ar\_addon\_init method), the memory pool created (and its child pools) are all global memory pools. When called with thread-context memory pool, the created child pools are thread-specific memory pools.

Multiple child memory pools can be created from a given memory pool. Creation of a child pool is always thread safe, so no synchronization is needed.

#### Syntax

```
create_pool (AR_AO_MPOOL *parentPool, 
char *poolName, 
AR_AO_MPOOL **newPool); 
```

create\_pool parameters

| Parameter | Type | Description |
| --- | --- | --- |
| parentPool | AR\_AO\_MPOOL\* | The pool to allocate from (required). |
| poolName | char\* | The new memory pool name (optional).<br><br>Information note<br><br>The poolName value is assumed to be a static, unmanaged space that does not need to be freed. The value will not be copied internally. |
| newPool | AR\_AO\_MPOOL\*\* | The address of the variable where to store the pointer to the new memory pool. |

#### Examples

Example 1:

```
AR_AO_MPOOL*		init_pool;AR_AO_MEM->create_pool(context->addonPool, "ADDON_XYZ_POOL", &init_pool);
```

Example 2:

```
AR_AO_MPOOL*		init_child_pool;AR_AO_MEM->create_pool(init_pool, "ADDON_XYZ_CHILD_POOL", &init_child_pool);
```

### destroy\_pool

Deletes the given pool and deallocates the memory associated with it. Any pool allocated by the Memory Management APIs can be destroyed using this method.

Information note

If a pool is expected to be re-created later, then it is recommended to use the clear\_pool method instead of the destroy\_pool method, as doing so will result in better performance and reduced memory load.

#### Syntax

```
destroy_pool (AR_AO_MPOOL **pool); 
```

destroy\_pool parameters

| Parameter | Type | Description |
| --- | --- | --- |
| Pool | AR\_AO\_MPOOL | The address of the variable pointing to the pool to destroy. The variable will be set to NULL. |

#### Example

```
AR_AO_MEM->destroy_pool(&init_pool);
```

### clear\_pool

Deallocates the memory allocations associated with a given pool and destroys all child pools created from it. The clear\_pool method also clears all metadata set with the set\_ctx method.

#### Syntax

```
clear_pool (AR_AO_MPOOL *pool); 
```

clear\_pool parameters

| Parameter | Type | Description |
| --- | --- | --- |
| pool | AR\_AO\_MPOOL\* | The pool to clear. |

#### Example

```
AR_AO_MEM->clear_pool(init_pool);
```

### calloc

This method allocates a memory buffer of the specified length from a given memory pool. The allocated buffer content is set to zeros.

Information note

* Use of global memory pools for allocation outside of the ADDON initialization must be protected to prevent concurrent allocation from the same memory pool in different threads. Use of a thread-specific memory pool in the thread under which it was created does not need concurrency protection (see get\_ctx\_pool when creating thread-specific pools). However, it is not thread safe to do this on the same pool.

* Failure in memory allocation will cause the process to abort.

#### Syntax

```
calloc (AR_AO_MPOOL *pool, 
size_t *size
); 
```

calloc parameters

| Parameter | Type | Description |
| --- | --- | --- |
| pool | AR\_AO\_MPOOL\* | The pool to allocate memory from. |
| size | size\_t | The size of the buffer to allocate. |

#### Example

```
init_sample_data = AR_AO_MEM->calloc(init_pool, sizeof(SAMPLE_DATA));
```

### get\_ctx\_pool

Returns the context-thread memory pool. While this pool can be used directly to allocate buffers, it must never be cleared or destroyed explicitly by the add-on, as all add-ons used from the same thread share this pool. For this reason, it is recommended for add-ons to create their own thread-specific memory pool from the context-thread memory pool.

Use of the context-thread memory pool, as well as pools created from it, does not require protection when done in the same thread under which they were created.

The context-thread memory pool (and pools created from it) will be destroyed automatically when the thread ends.

#### Syntax

```
get_ctx_pool (char *poolName, 
AR_AO_MPOOL **pool 
);
```

get\_ctx\_pool parameters

| Parameter | Type | Description |
| --- | --- | --- |
| poolName | char | The pool name if one needs to be created (optional). |
| pool | AR\_AO\_MPOOL | The ctx pool address that the function returns. |

#### Example

```
AR_AO_MEM->get_ctx_pool(NULL, &sample_pool);
```

### get\_ctx

Gets the metadata from the given memory pool for a given key name. This will return a null data value if the key has not yet been set (see set\_ctx).

#### Syntax

```
get_ctx (AR_AO_MPOOL *pool, 
char *key, 
void **data 
);
```

get\_ctx parameters

| Parameter | Type | Description |
| --- | --- | --- |
| pool | AR\_AO\_MPOOL | The ctx pool to get the metadata from. |
| key | char | The key for the metadata to retrieve. |
| data | void | The user metadata associated with the returned pool. |

#### Example

```
AR_AO_MEM->get_ctx(sample_pool, "SAMPLE_DATA", &sample_data);
```

### set\_ctx

Sets metadata on the thread pool for a given key. This value can be retrieved by key name using the get\_ctx method.

The set\_ctx method allows registering of an optional cleanup function to be called when the memory pool is cleaned or destroyed. The cleanup function receives a single, void\* parameter which is the data that was associated with the key.

Information note

The key and the data pointers are stored as-is (with no copying). The caller must ensure they are valid until the pool is destroyed.

#### Syntax

```
set_ctx (AR_AO_MPOOL *pool, 
char *key, 
void *data, 
AR_ADDONS_MEM_CTX_CLEANUP cleanup
); 
```

set\_ctx parameters

| Parameter | Type | Description |
| --- | --- | --- |
| pool | AR\_AO\_MPOOL\* | The ctx pool. |
| key | char\* | The key for the metadata to retrieve. |
| data | void\* | The user metadata to be associated with the pool. |
| cleanup | AR\_ADDONS\_MEM\_CTX\_CLEANUP | A pointer to a cleanup function with a single void\* parameter, that is called with the data value when the pool is destroyed. |

#### Example

```
rc = AR_AO_MEM->set_ctx(sample_pool, "SAMPLE_DATA", sample_data, 0);
```

## AR\_ADDONS\_STATUS

All Replicate ADDON Memory Management API calls, except for calloc, return an AR\_ADDONS\_STATUS status value.